/*
 **************************************************************************************
 *                        桂林光通电子工程公司
 *
 *  文件描述： OTDR事件相关头文件
 *  文件名  ： Event.h
 *  创建者  ： 彭怀敏
 *  创建日期： 2017年 05月 09日 星期二 08:37:19 CST
 *  当前版本： v2.0
 *
 **************************************************************************************
*/
#ifndef _EVENT_H__
#define _EVENT_H__

#ifdef __cplusplus
extern "C" {
#endif  // __cplusplus

#include <math.h>


/*
 **************************************************************************************
 *   数据结构定义
 **************************************************************************************
*/
#define	C				  299792458		// 光速 3e8

typedef struct		// 2010-12-8 11:47:39	2010-12-9 17:45:52
{
	int	*TotalEvent;		// 指向全部事件点的指针		使用在寻找事件点函数中
	int	TotalEventNum;		// 全部事件点的数目			使用在寻找事件点函数中
	int	FinalEvent[MAX_EVENT_NUM];		// 指向最终事件点的指针		使用在过滤事件点函数中
	int	FinalEventEnd[MAX_EVENT_NUM];		// 指向最终事件点末点的指针	使用在过滤事件点函数中
	int	FinalEventNum;		// 最终事件点的数目			使用在过滤事件点函数中
	int	EventType[MAX_EVENT_NUM];			// 指向最终事件点类型的指针	使用在过滤事件点函数中
	int	SaturateEvent[MAX_EVENT_NUM];     // 保存饱和平顶的事件点下标 使用在确定结束事件点函数中
	int	SatEventNum;        // 保存饱和平顶的事件点个数 使用在确定结束事件点函数中
}Event_t;

// 成组事件的起点
typedef struct
{
    int   EventGroupStart[MAX_EVENT_NUM];
    int   EventGroupNum;
}EventGroupStart_t;

// 事件点处理数据结构，用于搜索事件点函数FindEventPoints中
#define	EVENT_TYPE_START		0			// 起始事件
#define	EVENT_TYPE_REFLECT		1			// 反射事件
#define	EVENT_TYPE_NONREFLECT	2			// 非反射事件
#define	EVENT_TYPE_END			3			// 结束事件
#define	EVENT_TYPE_FIBER		4			// 光纤事件
#define EVENT_TYPE_PROBABLE     5           // 新增可能的事件
#define EVENT_TYPE_GHOST        90          // 可能的鬼影
#define EVENT_TYPE_FUCK         100         // 让我不爽的事件点
#define	EVENT_TYPE_UNDEF		0xFEDCBA	// 未确定事件，留待以后确定

/******************** SR_4731i02.pdf SOR 规定的事件类型代码 ********************
 *
 * The Event Code field provides a six-character alpha/numeric string to describe
 * the type of event that has been identified. This field will be used to report an
 * event that is saturating the OTDR’s receiver. The code is as follows:
 *
 *  First Position:
 *      0 = Non-reflective event
 *      1 = Reflective Event
 *      2 = Saturated/clipped reflective event
 *  Second Position:
 *      A = Added by the user
 *      M = Relocated by the user
 *      E = End of fiber
 *      F = Found by software
 *      O = Out of range without finding end of fiber
 *      D = Modified end of fiber
 ******************************************************************************/

//    归纳整理第二个位置的信息，有如下表格
//    ||==========|==========|==========||
//    ||          | 中间事件 | 结束事件 ||
//    ||----------|----------|----------||
//    || 用户修改 |  A   M   |    D     ||
//    ||----------|----------|----------||
//    || 软件找到 |    F     |  E   O   ||
//    ||==========|==========|==========||

#define EC1_NONREFLECT  0
#define EC1_REFLECT     1
#define EC1_SATURATE    2

#define EC2_A          'A'
#define EC2_M          'M'
#define EC2_E          'E'
#define EC2_F          'F'
#define EC2_O          'O'
#define EC2_D          'D'

/*
 **************************************************************************************
 **************************************************************************************
*/
// 最值宏定义
#define	MAX(a, b)	    (((a) > (b)) ? (a) : (b))
#define	MIN(a, b)	    (((a) < (b)) ? (a) : (b))

// 数据类型定义
#define DATA_TYPE_CHAR      0
#define DATA_TYPE_SHORT     1
#define DATA_TYPE_INT       2
#define DATA_TYPE_LONG      3
#define DATA_TYPE_FLOAT     4
#define DATA_TYPE_DOUBLE    5

/*
 **************************************************************************************
 * 函数原型声明
 **************************************************************************************
*/
// OtdrEventTools.c
float CalculateFiberSectionAttenCoef(const OtdrTestParam_t *tp, const float Ai[], \
            int FinalEvent[], int FinalEventEnd[], int EventNum, int Ei, float *b);
float CalculateEventPoint_IL_RL(const float Ai[], int FinalEvent[], int FinalEventEnd[], const float AC[], const float b[], \
                                const EventGroupStart_t *EGS, int Gi, float bsc, float IL[], float RL[]);
float CalculateFSL(const int FinalEvent[], const float AC[], \
                   const EventGroupStart_t *EGS, float FSL[]);
float CalculateEventPointTL(const int FinalEvent[], const float AC[], const float IL[], \
                            const EventGroupStart_t *EGS, float FSL[], float TL[]);
void NormalizeAC_RL(float ppm, float AC[], float RL[], int EventType[], int EventNum);
int InitEventGroupStart(const float AttenCoef[], EventGroupStart_t *EGS, int EventNum);
void lsaFitOTDRData(const OtdrTestResult_t *result, float *LinearOut);
int getABResult(const OtdrTestResult_t *result, int Apos, int Bpos, \
        float *distance, float *loss2PT, float *coef2PT, float *lossLSA, float *coefLSA);
void getTotalLoss(const OtdrTestResult_t *result, const int pos[], float loss[], int n);
float getDataSpace(OtdrTestResult_t *tr);
float index2Length(unsigned int index, float data_space);
int length2Index(float len, float data_space);
int getDisplayPoints(int MeasureLength_m, float data_space);
int OtdrBuildEventList(OtdrTestResult_t *tr);

// Utility.c
void LeastSquareErrorMethod(const float di[], int n, float *k, float *b);
void LeastSquareMethod(const float di[], int from, int to, float *k, float *b);
float FastLog10(float x);
void iMaxValue(const int *input, int from, int to, int *MV, int *pos);
void fMaxValue(const float *input, int from, int to, float *MV, int *pos);
void iMinValue(const int *input, int from, int to, int *MV, int *pos);
void fMinValue(const float *input, int from, int to, float *MV, int *pos);
void iMinValueEQ(const int *input, int from, int to, int *MV, int *pos);
void fMinValueEQ(const float *input, int from, int to, float *MV, int *pos);
void iMeanValue(const int *input, int from, int to, int *MV);
void fMeanValue(const float *input, int from, int to, float *MV);
int TurningPoint(const int input[], int from, int to, char *direction);
int GetCount(const int input[], int from, int to, int dst, int tol);
int qsort_cmp(const void *a , const void *b);
float HostFloat2NetworkFloat(float f);
float NetworkFloat2HostFloat(float f);
int qsort_partitions(int buf[], int low, int high);
int kth_smallest(int buf[], int n, int k);
void saveint(char *filename, int buf[], int n);
void savefloat(char *filename, float buf[], int n);
char* CurrentDateTime(char timebuf[]);

#ifdef __cplusplus
}
#endif // __cplusplus

#endif  /* _EVENT_H__ */

/*
 **************************************************************************************
 *    End    of    File
 **************************************************************************************
*/
